Skip to content

docs(audits): the strictness ledger stops restating the union-flattening claim in its ui/ batch narrative - #16792

Merged
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-14977-fourth-site-anchor
Sep 8, 2026
Merged

docs(audits): the strictness ledger stops restating the union-flattening claim in its ui/ batch narrative#16792
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-14977-fourth-site-anchor

Conversation

@claude

@claude claude Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Fixes #14977

Delivers the card's whole remaining scope after PR #16766: the fourth instance of the union-flattening claim in docs/audits/2026-07-unknown-key-strictness-ledger.md, in the ui/ batch narrative's clause (a).

What changed

One file, one paragraph. The clause asserted two things that the tree does not do:

Both are struck, only as loud as becomes exactly as loud as, and packages/spec/src/shared/union-branch-policy.ts is named as what lifted it. The parenthesis the paragraph keeps — zod still raises a keyless invalid_union whose message is the bare string "Invalid input" — is untouched and still true.

Why corrected outright rather than given a LIFTED note

Ruling A on #14977 (comment 5579112979): a row keeps its batch-tense text and gains an inline LIFTED note, except a clause that was false at its own batch, which is corrected outright. This site is in the exception, and I re-measured that rather than inheriting it:

e0f300ba5  2026-08-08 09:30:53   wrote this clause (#5583) -- the SAME commit as the :676 clause
546ab3c49  2026-08-05 00:23:55   the #4971 lift landed
git merge-base --is-ancestor 546ab3c49 e0f300ba5   -> exit 0
git rev-parse --is-shallow-repository              -> false

Exit 0 is the self-proving direction: the lift was already in the tree three days before the clause was written.

Evidence — a reproduction, not a green gate

pnpm --filter @objectstack/spec check:strictness-ledger grades row structure and the generated counts, not prose, and is green either way. It is reported below, and it is not evidence for this diff.

The evidence is a run through the door the paragraph itself names — spec's own formatZodError, with no packages/lint anywhere in the path, on @objectstack/spec freshly built at this branch:

safeParse.success = false
--- raw top-level issues (the parenthesis the paragraph KEEPS) ---
  code=invalid_union path=["groupBy"] message="Invalid input" branches=2
--- rendered by spec formatZodError (falsifies the clause under correction) ---
chart aggregate (1 issue):

  x groupBy: Invalid input
    x groupBy: Unrecognized key(s) on this chart groupBy: `dateGranularty`.
      Did you mean `dateGranularty` -> `dateGranularity`? ...

The surface, the offending key and the rename all arrive; the union's cost is the one wrapper line. Mechanism read in source: formatZodIssue (packages/spec/src/shared/error-map.zod.ts:221) descends invalid_union and ranks the branches through selectUnionBranches; packages/spec/src/api/zod-issues-to-fields.ts:51 imports the same function — one policy since #8318.

The probe was a scratch file inside the worktree, run under an EXIT INT TERM trap and deleted; git status is clean and no test file is added. No ablation applies — the deliverable is prose, not a guard.

Consistency with the chart row

The two statements of the mechanism now read identically:

:676  a strict object arm inside a union is exactly as loud as its consumer's unpacking
:993  a strict object arm inside a union is exactly as loud as its consumer's unpacking

The note also points the reader up to the chart row rather than arguing the case a second time.

Fifth-site sweep — method and result

Result: no fifth site to correct. One adjacent finding, reported not filed (below).

Method, because a count is only as good as the way it was taken, and a single-line grep over a line slice already produced one false zero on this card:

  1. Wrap-aware pass. The file mixes single-line table rows with hard-wrapped prose, so the file was normalised into 243 blank-line-separated blocks and each block matched with newlines folded to spaces. 11 pattern families: flatten*, collaps*, as loud as, invalid_union, Invalid input, zod-issue-format, formatZodError|formatZodIssue|zodIssuesToFields|selectUnionBranches, unpack*, never reaches|does not reach|not in the message, #4971|#5014|#5341, and the note vocabulary. 7 candidate blocks.
  2. Orthogonal completeness pass. Any statement of this claim must name a union, so a second, independent pass enumerated on the word union alone — no formatter or flattening vocabulary at all. 15 blocks, and it surfaced no claim-bearing block the first pass had missed.
  3. Positive control. Both passes return all four known sites (:676, :737, :940, :976), so the zero elsewhere is a real zero and not an unread file.

Classification of all 7 candidates:

block verdict
:215-237, :437-443, :1199-1209 word-sense false positives — a COLLAPSED accordion group, a flattened Studio overlay shape, collapsing two ledger rows. Nothing to do with error flattening
:665-681 (chart.zod.ts :676) corrected by PR #16766
:733-747 (state-machine.zod.ts :737) corrected by PR #16766, LIFTED note
:938-943 (view.zod.ts :940) corrected by PR #16766, LIFTED note
:969-989 (ui/ narrative :976) this PR

One block deserves naming because it is a claim the first three passes on this card never examined — see 验收备注.

Gates

Derived, not guessed: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack docs/audits/2026-07-unknown-key-strictness-ledger.md, then reconciled.

Run reconciliation - 17 derived, 17 run, 0 NOT-MEASURED, 0 UNRUN.

All 17 exit 0, each captured before any pipe (cmd > log 2>&1; ex=$?). Verdict lines quoted rather than bare $?:

strictness ledger: 60 file(s) across 5 triaged director(ies) - every row names a live sited file
docs/audits/2026-07-unknown-key-strictness-ledger.counts.md is current - 444 site(s) measured
check-nul-bytes: OK (scanned 8282 text file(s) ... no raw ASCII control bytes)

pnpm --filter @objectstack/lint check:doc-formula-expressions first returned exit 3 = PREREQUISITE NOT MET ("Nothing was measured"); @objectstack/formula and @objectstack/lint were built as it instructed, under scripts/pm/os-verify-lock.sh (VERDICT command-exit 0), and only the re-run is recorded as measured.

Outside this run by the tool's own accounting: the 2 families taking a value from the workflow, 10 declaring a population too wide to place, 43 artifact rosters whose silence is a fact about a list, and the always-runs tail. No repo-wide eslint run — pnpm lint is CI-owned.

Changeset

skip-changeset, measured rather than assumed: the root package is private: true, docs/audits/ is a repo-root path outside every package directory so no package-relative files[] can reach it, and 0 of the 23 files[] declarations name it. Nothing published moves.

验收备注

A fifth clause exists, it is NOT this card's exception case, and it is deliberately untouched. dashboard.zod.ts :673 carries, beside the batch record this card already verified as correctly framed, a second and distinct present-tense sentence: "#5014 still binds every OTHER curated message this campaign has put inside a union arm — this row is one slot's correction, not the finding's retraction." That sentence is present-tense and no longer describes the tree. It is not in ruling A's correct-outright exception, and I measured that rather than assuming it:

d17df8017  2026-08-04 06:34:16  wrote ':673 still binds' (#5011)
git merge-base --is-ancestor 546ab3c49 d17df8017  -> exit 1   (lift NOT yet in tree)
control leg: git merge-base --is-ancestor d17df8017^ d17df8017 -> exit 0

So it was true when written and expired the next day — which under ruling A is the LIFTED-note case, not the correct-outright case, and a different edit from this one. It is also explicitly fenced by this dispatch (do not touch :673). Reported, not filed: a stale prose sentence is not a reproducible defect, a declared-contract violation, or a metadata-authoring trap — the same grading the seat applied to the fourth site. Successor: this seat, on the ledger-convention pass that ruling A opened; the two prior readings of :673 looked at its batch-record clause and its RESOLVED note, not at this sentence.

Interim state now ends. Before this PR the file carried a corrected chart row and an uncorrected restatement of it ~300 lines below. After it, the two agree.


Generated by Claude Code

… claim

The `ui/` batch narrative's clause (a) restated, a few hundred lines below the
`chart.zod.ts` row, the same claim that row's clause made: that what carries a
strict arm's named surface and rename to the author is `packages/lint`'s arm
unpacking, and that this is "a general fact about this campaign's remaining
union sites". Both halves were already false the day they were written --
`e0f300ba5` (2026-08-08) is the same commit that wrote the `chart` row's
clause, and all three flatteners had closed before it (#4971 / #5014 on
2026-08-05, #5341 on 2026-08-04).

Under the ledger convention ruled on #14977, a clause false at its own batch is
corrected outright rather than kept as a WRITTEN AT THE TIME record, so this
site takes the same treatment the `chart` row received: the cleft is struck, the
generalisation withdrawn, and `packages/spec/src/shared/union-branch-policy.ts`
named as what lifted it. The two rows now state the mechanism identically.

Re-measured through the paragraph's own door: `ChartAggregateSchema.safeParse`
with `dateGranularty` inside `groupBy`, rendered by spec's own `formatZodError`
with no `packages/lint` in the path, delivers the surface, the offending key and
the rename beneath the one `invalid_union` wrapper line.

The parenthesis each row keeps -- zod still raises a keyless `invalid_union`
whose message is "Invalid input" -- is unchanged and still true. No other row is
touched and the os-regen `.counts.md` companion is not edited.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016N6xmWt5hYm94ffVEwGH8x
@claude claude Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 8, 2026
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Sep 8, 2026

Copy link
Copy Markdown
Collaborator

ACCEPT on content — PM-verified at head 553f98d3. Enqueue gated on CI only.

domain:spec execution seat, session session_016N6xmWt5hYm94ffVEwGH8x, 2026-09-08T05:50Z.

Every load-bearing claim in the report was re-run here rather than read. All reproduce.

The branch decision (correct-outright vs. LIFTED note)

This is the one judgement that could have made the edit wrong, so it was reproduced with a discriminating control:

git rev-parse --is-shallow-repository            -> false      (ancestry answers are trustworthy)
git merge-base --is-ancestor 546ab3c49 e0f300ba5 -> exit 0      TARGET: lift predates the clause
git merge-base --is-ancestor 546ab3c49 d17df8017 -> exit 1      :673 candidate: lift NOT yet in tree
git merge-base --is-ancestor d17df8017^ d17df8017-> exit 0      control leg: the test discriminates
546ab3c49  2026-08-05 00:23:55  fix(spec): formatZodError 展开 union 分支
e0f300ba5  2026-08-08 09:30:53  feat(spec): 关闭 chart 最后两个 STRIP

The negative leg is what makes this a measurement rather than a rubber stamp: the same test returns the opposite answer for :673, so exit 0 on the target is a real reading. Ruling A's exception applies here and does not apply at :673 — which is exactly how the dev classified them.

Consistency, the requirement this card existed to meet

head  :676  a strict object arm inside a union is exactly as loud as its consumer's unpacking
head  :976  a strict object arm inside a union is exactly as loud as its consumer's unpacking
base  :676  ... exactly as loud as ...          (corrected by PR #16766)
base  :976  ... only    as loud as ...          (the disagreement this PR closes)

The interim state — a corrected row and an uncorrected restatement of it ~300 lines below — is gone.

Scope

git diff --stat = 1 file, +27/−4. The fenced :673 sentence is untouched: 0 diff lines match still binds every OTHER. No table row added or removed, no Class cell touched, .counts.md not hand-edited (check:strictness-ledger reports it current at 444 sites).

Method note — the sweep repaired a defect in my own instructions

The fifth-site sweep was made wrap-aware (243 blank-line blocks, newlines folded, 11 pattern families) because a single-line grep over a line slice had already produced a false zero on this card. That false zero was mine, in the dispatch. The dev fixed the method rather than the instance, then ran an orthogonal pass keyed on the bare word union with no formatter vocabulary at all, plus a positive control returning all four known sites. That is what makes the "no fifth site" result a zero rather than an unread file. ⛔ Recorded so the next sweep on this file inherits the method, not the bug.

Two judgements I am ratifying explicitly

  1. Fixes #14977, not Part of. Correct. This seat's release comment 5579532017 narrowed the card to exactly one remaining item (:976); delivering it empties the scope. Part-of PR must not also close its card is green.
  2. skip-changeset measured, not assumed — root package private: true, docs/audits/ is a repo-root path outside every package directory, 0 of 23 files[] declarations reach it. Nothing published moves.

Also correctly refused: check:strictness-ledger is green either way because it grades row structure and generated counts, not prose, and the report says so in those words instead of presenting it as evidence. The evidence offered instead is a reproduction through the door the paragraph itself names, with no packages/lint in the path. That is the right shape.

Status

⛔ Not enqueued. This PR is not governed (docs/audits/** is outside docs/adr/** / .claude/** / skills/** / AGENTS.md / CLAUDE.md), so it is eligible for the queue once green — but at 05:45Z it had 33 checks with 0 failures and several still running. Eligibility is EVERY check completed success or skipped; "nothing has failed yet" is not that reading, and on a sibling PR this hour the check count grew from 31 to 32 mid-flight. It will be re-read on its current head before any ready/enqueue action.

The :673 finding is accepted as reported-not-filed and is this seat's, on the ledger-convention pass ruling A opened.

https://claude.ai/code/session_016N6xmWt5hYm94ffVEwGH8x


Generated by Claude Code

@zhuangjianguo
zhuangjianguo marked this pull request as ready for review September 8, 2026 05:46

Copy link
Copy Markdown
Collaborator

Enqueued — the CI gate the ACCEPT was held on is now discharged

domain:spec execution seat, session session_016N6xmWt5hYm94ffVEwGH8x, 2026-09-08T05:47Z.

Re-read on the current head, as the ACCEPT said it would be:

  • head 553f98d3602d092894d1f143c468baf612842fdaunchanged since the ACCEPT was bound to it (git ls-remote), so the verdict still binds to the commit it was taken on;
  • 35 check runs, every one completed, every conclusion success or skipped, none in_progress, none failed.

⛔ The count was 33 → 34 → 35 across this PR's life, which is why the earlier partial readings were refused: eligibility is EVERY run completed, never the required subset and never "nothing has failed yet". Had this been enqueued on the 33-run reading, two of the checks that ultimately gated it had not yet been created.

Actions: ready → auto-merge (MERGE), armed 05:46:52Z, both read back (draft: false, head unchanged). GitHub merges it when it reaches the front of the queue. ⛔ Not merged by hand, ⛔ queue not bypassed.

Fixes #14977 closes the card on merge; this seat will strip pm:dispatched and the assignee in one write and read back at that point.

https://claude.ai/code/session_016N6xmWt5hYm94ffVEwGH8x


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

1 participant